package org.dfl.plugin.editor.contributionitems;

import org.dfl.core.utils.Utils;
import org.dfl.plugin.editor.model.DflDiagram;
import org.dfl.plugin.editor.model.DiagramListener;
import org.eclipse.jface.action.ContributionItem;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;

/**
 * contribution item that listens for diagram changes
 * @author Piotr Wlodarczyk
 *
 */
public abstract class FlowRunnerActionContributionItem extends ContributionItem implements DiagramListener{
	DflDiagram diagram = null;
	private ToolItem menuItem;
	
	public FlowRunnerActionContributionItem() {
		super();
		setDiagram(null);
	}

	public void setDiagram(DflDiagram diagram) {
		this.diagram = diagram;
		if(diagram!=null) diagram.addListener(this);
		update();
	}

	/**
	 * Computes the width required by control
	 * @param control The control to compute width
	 * @return int The width required
	 */
	protected int computeWidth(Control control) {
		if(control!=null)
			return control.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x;
		else
			return 0;
	}

	
	@Override
	public void fill(Composite parent) {
	}
	

	public void fill(ToolBar parent, int index) {
		menuItem = new ToolItem((ToolBar) parent, SWT.PUSH);
		menuItem.addListener(SWT.Selection, new Listener() {
			  public void handleEvent(Event e) {
			    itemSelected();
			  }
			});
		menuItem.setWidth(16);
		update();	
	}
	
	protected abstract void itemSelected();
	protected abstract void updateItem(ToolItem item);
	
	@Override
	public synchronized void update() {
		Utils.execAsynch(new Runnable() {
			public void run() {
				try {
					updateItem(menuItem);
				} catch (Throwable e) {}
			}
		});
		super.update();
	}
	
	@Override
	public void dispose() {
		if(diagram!=null) diagram.removeListener(this);
		super.dispose();
	}

	/** listeners **/
	public void diagramChanged(DflDiagram diagram) {
		update();
	}
	public void diagramEnabled(DflDiagram diagram, boolean enabled) {
		update();
	}

	public void diagramPaused(DflDiagram diagram) {
		update();
	}

	public void diagramResumed(DflDiagram diagram) {
		update();
	}

	public void diagramRun(DflDiagram diagram) {
		update();
	}

	public void diagramStopped(DflDiagram diagram) {
		update();
	}
	
	private boolean hadDataToRun = false;
	public void diagramHasDataToRun(DflDiagram diagram,boolean hasData){
		if(hasData!=hadDataToRun){
			hadDataToRun = hasData;
			update();
		}
	}
}
